package cn.hznc.controller.service.permission;

import cn.hutool.core.collection.CollectionUtil;
import cn.hznc.controller.service.UserService;
import cn.hznc.domain.entity.*;
import cn.hznc.domain.request.DynamicMenuRequest;
import cn.hznc.domain.request.permission.RolesPermissionReq;
import cn.hznc.domain.response.PageResult;
import cn.hznc.mapper.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class RolesPermissionService {
    @Resource
    private RolesPermissionMapper rolesPermissionMapper;
    @Resource
    private RolesMapper rolesMapper;
    @Resource
    private EmployeePermissionMapper employeePermissionMapper;
    @Resource
    private MenuMapper menuMapper;
    @Resource
    private UserService userService;

    public PageResult<RolesEntity> queryPageByRolesName(Integer pageSize, Integer pageNo, String rolesName){
        PageHelper.startPage(pageNo, pageSize);
        LambdaQueryWrapper<RolesEntity> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(rolesName)) {
            queryWrapper.like(RolesEntity::getRolesName, rolesName);
        }
        PageInfo<RolesEntity> result = new PageInfo<>(rolesMapper.selectList(queryWrapper));
        return new PageResult<>(result.getList(), result.getTotal());
    }
    public List<Integer> queryMenuByRolesId2(Integer rolesId){
        List<RolesConnectionEntity> menuListByRoleId =  rolesPermissionMapper.selectList(new LambdaQueryWrapper<RolesConnectionEntity>().eq(RolesConnectionEntity::getRolesId,rolesId));
        List<Integer> menuIdList = new ArrayList<>();
        menuListByRoleId.forEach( rolesConnectionEntity -> menuIdList.add(rolesConnectionEntity.getMenuId()));
        List<MenuEntity> menuEntityListByRoleId = menuMapper.selectBatchIds(menuIdList);
        List<Integer> menuEntityFatherIdList = new ArrayList<>();
        menuEntityListByRoleId.forEach( menuEntity ->
        {
            if(!menuEntityFatherIdList.contains(menuEntity.getFatherId())){
                menuEntityFatherIdList.add(menuEntity.getFatherId());
            }});
        menuIdList.removeAll(menuEntityFatherIdList);
        return menuIdList;
    }

    public List<MenuIdAndMenuNameEntity> queryMenuByRolesId(Integer rolesId){

        LambdaQueryWrapper<RolesConnectionEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RolesConnectionEntity::getRolesId,rolesId);
        List<RolesConnectionEntity> list =  rolesPermissionMapper.selectList(queryWrapper);
        List<MenuIdAndMenuNameEntity> menuList = new ArrayList<>();
        list.forEach(rolesConnectionEntity -> {
            MenuEntity menuEntity = menuMapper.selectById(rolesConnectionEntity.getMenuId());
            MenuIdAndMenuNameEntity menuIdAndMenuNameEntity = new MenuIdAndMenuNameEntity();
            menuIdAndMenuNameEntity.setLabel(menuEntity.getMenuName());
            menuIdAndMenuNameEntity.setValue(menuEntity.getId());
            menuList.add(menuIdAndMenuNameEntity);
        });
        return menuList;
    }

    public Object deleteRolesByRolesId(Integer rolesId){
        LambdaQueryWrapper<RolesConnectionEntity> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(RolesConnectionEntity::getRolesId,rolesId);
        LambdaQueryWrapper<RolesEntity> queryWrapper2 = new LambdaQueryWrapper<>();
        queryWrapper2.eq(RolesEntity::getId,rolesId);
        LambdaQueryWrapper<UserConnectionEntity> queryWrapper3 = new LambdaQueryWrapper<>();
        queryWrapper3.eq(UserConnectionEntity::getRolesId,rolesId);
        rolesMapper.delete(queryWrapper2);
        rolesPermissionMapper.delete(queryWrapper1);
        employeePermissionMapper.delete(queryWrapper3);
        return Boolean.TRUE;
    }
    public Object updateRolesByRolesIdAndMenuId2(RolesPermissionReq rolesPermissionReq){
        List<RolesConnectionEntity> oldRolesConnectionEntities =  rolesPermissionMapper.selectList(new LambdaQueryWrapper<RolesConnectionEntity>().eq(RolesConnectionEntity::getRolesId,rolesPermissionReq.getRolesId()));
        List<Integer> oldRoleMenuList = new ArrayList<>();
        oldRolesConnectionEntities.forEach(rolesConnectionEntity -> oldRoleMenuList.add(rolesConnectionEntity.getMenuId()));

        Set<Integer> newRoleMenuSet = new HashSet<>();

        List<Integer> menuIdList = rolesPermissionReq.getMenuIdList();//传入的菜单ID
        menuIdList.forEach( menuId -> {
            newRoleMenuSet.add(menuId);
            Integer fatherId = menuMapper.selectById(menuId).getFatherId();
            Integer depth = 0;
            while (fatherId != 1 && depth<10){
                newRoleMenuSet.add(fatherId);
                fatherId = menuMapper.selectById(fatherId).getFatherId();
                depth++;
            }
        });

        oldRolesConnectionEntities.forEach(rolesConnectionEntity -> rolesPermissionMapper.delete(new LambdaQueryWrapper<RolesConnectionEntity>().eq(RolesConnectionEntity::getRolesId,rolesConnectionEntity.getRolesId()).eq(RolesConnectionEntity::getMenuId,rolesConnectionEntity.getMenuId())));

        newRoleMenuSet.forEach(menuId->{
            RolesConnectionEntity rolesConnectionEntity = new RolesConnectionEntity();
            rolesConnectionEntity.setRolesId(rolesPermissionReq.getRolesId());
            rolesConnectionEntity.setMenuId(menuId);
            rolesPermissionMapper.insert(rolesConnectionEntity);
        });

        return Boolean.TRUE;
    }
    public Object updateRolesByRolesIdAndMenuId(RolesPermissionReq rolesPermissionReq){
        List<MenuIdAndMenuNameEntity> menuList = queryMenuByRolesId(rolesPermissionReq.getRolesId());
        List<Integer> menus = new ArrayList<>();
        menuList.forEach(menu ->{
            menus.add(menu.getValue());
        });
        List<Integer> menuIdList = rolesPermissionReq.getMenuIdList();

        menuIdList.forEach(menuEntity ->{
            if (menus.contains(menuEntity)){
                menus.remove(menuEntity);
                LambdaQueryWrapper<MenuEntity> queryWrapper4 = new LambdaQueryWrapper<>();
                queryWrapper4.eq(MenuEntity::getId,menuEntity);
                MenuEntity menuEntity2 = menuMapper.selectOne(queryWrapper4);
                LambdaQueryWrapper<MenuEntity> queryWrapper1 = new LambdaQueryWrapper<>();
                queryWrapper1.eq(MenuEntity::getFatherId,menuEntity);
                List<MenuEntity> menuEntityList = menuMapper.selectList(queryWrapper1);
                if (CollectionUtil.isNotEmpty(menuEntityList)&&menuEntity2.getFatherId()!=1){
                    menuEntityList.forEach(menuEntity1 -> {
                            menus.remove(menuEntity1.getId());

                    });
                }
            }else {
                LambdaQueryWrapper<MenuEntity> queryWrapper1 = new LambdaQueryWrapper<>();
                queryWrapper1.eq(MenuEntity::getFatherId,menuEntity);
                List<MenuEntity> menuEntityList = menuMapper.selectList(queryWrapper1);
                if (CollectionUtil.isNotEmpty(menuEntityList)){
                menuEntityList.forEach(menuEntity1 -> {
                    RolesConnectionEntity rolesConnectionEntity = new RolesConnectionEntity();
                    rolesConnectionEntity.setRolesId(rolesPermissionReq.getRolesId());
                    rolesConnectionEntity.setMenuId(menuEntity1.getId());
                    rolesPermissionMapper.insert(rolesConnectionEntity);
                });

            }
            RolesConnectionEntity rolesConnectionEntity = new RolesConnectionEntity();
            rolesConnectionEntity.setRolesId(rolesPermissionReq.getRolesId());
            rolesConnectionEntity.setMenuId(menuEntity);
            rolesPermissionMapper.insert(rolesConnectionEntity);
            }
        } );
        menus.forEach(menu ->{
                LambdaQueryWrapper<RolesConnectionEntity> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(RolesConnectionEntity::getRolesId,rolesPermissionReq.getRolesId());
                queryWrapper.eq(RolesConnectionEntity::getMenuId,menu);
                rolesPermissionMapper.delete(queryWrapper);
        });
        return Boolean.TRUE;
    }
    public List<DynamicMenuRequest> queryAllMenu2(){
        List<MenuEntity> menuEntityList = menuMapper.selectList(null);
        return userService.findChild(menuEntityList,1);
    }

    public List<MenuRelationEntity> queryAllMenu(){
        LambdaQueryWrapper<MenuEntity> queryWrapper1 = new LambdaQueryWrapper<>();
        List<MenuEntity> allMenuEntityList = menuMapper.selectList(queryWrapper1);
        List<MenuRelationEntity> menuRelationEntityList = new ArrayList<>();
        allMenuEntityList.forEach(menuEntity ->{
            LambdaQueryWrapper<MenuEntity> queryWrapper2 = new LambdaQueryWrapper<>();
            queryWrapper2.eq(MenuEntity::getFatherId,menuEntity.getId());
            List<MenuEntity> menuEntityList = menuMapper.selectList(queryWrapper2);
            if (!menuEntityList.isEmpty()){
                List<MenuIdAndMenuNameEntity> arrayList = new ArrayList<>();
                menuEntityList.forEach( menuEntity1 -> {
                    MenuIdAndMenuNameEntity menuIdAndMenuNameEntity = new MenuIdAndMenuNameEntity();
                    menuIdAndMenuNameEntity.setLabel(menuEntity1.getMenuName());
                    menuIdAndMenuNameEntity.setValue(menuEntity1.getId());
                    arrayList.add(menuIdAndMenuNameEntity);
                });
                MenuRelationEntity menuRelationEntity = new MenuRelationEntity();
                menuRelationEntity.setFatherName(menuEntity.getMenuName());
                menuRelationEntity.setMenuIdAndMenuNameEntityList(arrayList);
                menuRelationEntity.setFatherId(menuEntity.getId());
                menuRelationEntityList.add(menuRelationEntity);
            }
        });

        return menuRelationEntityList;
    }
    @Transactional
    public void insertRoles(String rolesName) throws Exception{
        LambdaQueryWrapper<RolesEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(RolesEntity::getRolesName,rolesName);
        RolesEntity rolesEntity = rolesMapper.selectOne(lambdaQueryWrapper);
        if (rolesEntity != null){
            throw new Exception("该角色名称已存在");
        }else {
            RolesEntity rolesEntity1 = new RolesEntity();
            rolesEntity1.setRolesName(rolesName);
            rolesMapper.insert(rolesEntity1);
            LambdaQueryWrapper<RolesEntity> lambdaQueryWrapper2 = new LambdaQueryWrapper<>();
            lambdaQueryWrapper2.eq(RolesEntity::getRolesName,rolesName);
            List<RolesEntity> rolesEntity2 = rolesMapper.selectList(lambdaQueryWrapper2);

            LambdaQueryWrapper<MenuEntity> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
            lambdaQueryWrapper1.eq(MenuEntity::getFatherId,1);
            List<MenuEntity> menuEntityList = menuMapper.selectList(lambdaQueryWrapper1);
            menuEntityList.forEach(menuEntity -> {
                RolesConnectionEntity rolesConnectionEntity = new RolesConnectionEntity();
                if (CollectionUtil.isNotEmpty(rolesEntity2)){
                    rolesConnectionEntity.setRolesId(rolesEntity2.get(0).getId());
                    rolesConnectionEntity.setMenuId(menuEntity.getId());
                    rolesPermissionMapper.insert(rolesConnectionEntity);
                }

            });

        }
    }
}
